using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using OpenComposite.Repository.Properties;
using System.Drawing;
using OpenComposite.EII.Repository;
using System.Diagnostics;
using System.Data;

namespace OpenComposite.EII.Designer.SCA
{
	public class OrchestrationComponentSymbol : ServiceComponentSymbol
	{
		#region Initialization
		public OrchestrationComponentSymbol()
		{
			init();
		}
		private void init()
		{
			this.BeginUpdate();

			this.BackBrushMode = BackgroundBrushMode.LinearGradient;
			this.BackLinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
			this.BackColor = Color.FromArgb(204, 226, 255);
			this.BackColor2 = Color.White;

			this.ContextMenuStrip = new ContextMenuStrip();
			//this.ContextMenuStrip.Items.Add(
			//    new ToolStripMenuItem("Create/Edit Orchestration...", 
			//        Resources.ico_process.ToBitmap(), 
			//        new EventHandler(context_CreateProcess)));
			//this.ContextMenuStrip.Items.Add(
			//    new ToolStripMenuItem("Create/Open Orchestration View...", 
			//        Resources.ico_process.ToBitmap(), 
			//        new EventHandler(context_CreateProcess)));

			operationProcess = null;

			this.EndUpdate();
		}
		#endregion

		#region Public Members

		#region Properties
		public Operation ProcessOperation
		{
			get
			{
				if ( operationProcess == null )
					searchForProcessOperation();
				return operationProcess;
			}
			set { operationProcess = value; }
		}
		#endregion

		#region Methods
		public override void PaintBackground(PaintEventArgs pe)
		{
			base.PaintBackground(pe);

			Rectangle rc = this.ClientRectangle;
			Point pt = this.PointToDesignerView(new Point(rc.X, rc.Bottom - 16));
			pe.Graphics.DrawIcon(Resources.ico_workflow, pt.X, pt.Y);
		}
		public override void InitializeLoaded()
		{
			base.InitializeLoaded();
			searchForProcessOperation();
		}
		public override void Load(int idRepository, int idDomain)
		{
			//_idPoliciesFolder = -1;
			//_idRulesFolder = -1;
			//_idVariablesFolder = -1;

			//List<GenericFolder> folders = Global.Data.GetRepositoryHierarchyChildRepositoryList<GenericFolder>(ItemType.Component, this.RepositoryItem.ID, ItemType.GenericFolder);
			//foreach ( GenericFolder folder in folders ) {
			//    if ( folder.AllowedChildTypes.Contains(ItemType.BPolicy) ) {
			//        _idPoliciesFolder = folder.ID;
			//    } else if ( folder.AllowedChildTypes.Contains(ItemType.Noun) ) {
			//        _idVariablesFolder = folder.ID;
			//    } else if ( folder.AllowedChildTypes.Contains(ItemType.BRule) ) {
			//        _idRulesFolder = folder.ID;
			//    }
			//}
			base.Load(idRepository, idDomain);
		}
		public override bool Save(int idRepository, int idDomain)
		{
			bool ok = base.Save(idRepository, idDomain);
			if ( ok ) {
				RepositoryService repSvc = GetService(typeof(RepositoryService)) as RepositoryService;
				Debug.Assert(repSvc != null, "Repository Service missing.");

				#region old code
				//GenericFolder folder;
				//#region Business Policies folder
				//if ( _idPoliciesFolder <= 0 ) {
				//    folder = repSvc.GetNewItem(ItemType.GenericFolder, false, this.RepositoryItem) as GenericFolder;
				//    if ( folder != null ) {
				//        folder.Name = "Business Policies";
				//        folder.ItemTypes = new ItemType[] { ItemType.BPolicy };
				//        folder.Save();
				//        _idPoliciesFolder = folder.ID;
				//    }
				//} else {
				//    Global.Data.AddRepositoryHierarchy(this.RepositoryItem.RepositoryItemType,
				//                                       this.RepositoryItem.ID,
				//                                       ItemType.GenericFolder,
				//                                       _idPoliciesFolder,
				//                                       Global.Status.CurrentRepositoryId);
				//}
				//#endregion
				//#region Process Variables folder
				//if ( _idVariablesFolder <= 0 ) {
				//    folder = repSvc.GetNewItem(ItemType.GenericFolder, false, this.RepositoryItem) as GenericFolder;
				//    if ( folder != null ) {
				//        folder.Name = "Process Variables";
				//        folder.ItemTypes = new ItemType[] { ItemType.Noun };
				//        folder.Save();
				//        _idVariablesFolder = folder.ID;
				//    }
				//} else {
				//    Global.Data.AddRepositoryHierarchy(this.RepositoryItem.RepositoryItemType,
				//                                       this.RepositoryItem.ID,
				//                                       ItemType.GenericFolder,
				//                                       _idVariablesFolder,
				//                                       Global.Status.CurrentRepositoryId);
				//}
				//#endregion
				//#region Process Rule folder
				//if ( _idRulesFolder <= 0 ) {
				//    folder = repSvc.GetNewItem(ItemType.GenericFolder, false, this.RepositoryItem) as GenericFolder;
				//    if ( folder != null ) {
				//        folder.Name = "Process Rules";
				//        folder.ItemTypes = new ItemType[] { ItemType.BRule };
				//        folder.Save();
				//        _idRulesFolder = folder.ID;
				//    }
				//} else {
				//    Global.Data.AddRepositoryHierarchy(this.RepositoryItem.RepositoryItemType,
				//                                       this.RepositoryItem.ID,
				//                                       ItemType.GenericFolder,
				//                                       _idRulesFolder,
				//                                       Global.Status.CurrentRepositoryId);
				//}
				//#endregion
				#endregion
				//#region add used policies to Business Policies folder
				//if ( _idPoliciesFolder > 0 && this.ProcessOperation != null ) {
				//    Repository.Workflow wf = this.ProcessOperation.GetWorkflow();
				//    if ( wf != null ) {
				//        foreach ( int ruleid in wf.GetRuleIDs() ) {
				//            DataTable dt = Global.Data.GetRepositoryParentsOfType(ItemType.BRule, ruleid, ItemType.BPolicy);
				//            if ( dt != null && dt.Rows.Count > 0 ) {
				//                RepositoryItemBase c = repSvc.GetItem(ItemType.BPolicy, (int)dt.Rows[0]["parent_id"], false);
				//                Global.Data.AddRepositoryHierarchy(
				//                    wf.BusinessPoliciesFolder, c, Global.Status.CurrentRepositoryId);
				//            }
				//        }
				//    }
				//}
				//#endregion
			}
			return ok;
		}
		#endregion

		#endregion

		#region Protected Members

		#region Variables
		protected Operation operationProcess;
		#endregion

		protected override void OnModeChanged(EventArgs e)
		{
			DesignController dc = this.DesignerViewControl.DesignController as DesignController;
			if ( dc == null ) return;

			this.ContextMenuStrip.Items[3].Visible = false;// Create C# Web Service
			this.ContextMenuStrip.Items[4].Visible = false;// Create C# Class
			this.ContextMenuStrip.Items[5].Visible = false;

			ServiceModule svcMdl = (ServiceModule)dc.DiagramItem;
			if ( svcMdl.Workflow.Type == WorkflowType.Business_Process ) {
				this.ContextMenuStrip.Items[0].Visible = false;
			} else {
				this.ContextMenuStrip.Items[0].Visible = false;
				this.ContextMenuStrip.Items[1].Visible = false;
				this.ContextMenuStrip.Items[2].Visible = false;
			}
		}
		#endregion

		#region Private Members

		#region Variables
		//private int _idPoliciesFolder;
		//private int _idVariablesFolder;
		//private int _idRulesFolder;
		#endregion

		#region Methods
		private void searchForProcessOperation()
		{
			operationProcess = null;
			foreach ( InterfaceSymbol isymbol in listInterfaces ) {
				foreach ( Operation op in isymbol.Operations ) {
					if ( op.WorkflowId > 0 )
						operationProcess = op;
				}
			}
		}
		#endregion

		#region Event Handlers
		private void context_CreateProcess(object sender, EventArgs e)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			DesignController dc = this.DesignerViewControl.DesignController as DesignController;
			if ( dc == null )
				return;

			ServiceModule svcMdl = (ServiceModule)dc.DiagramItem;
			if ( svcMdl.Workflow.Type == WorkflowType.Business_Process ) {

				RepositoryService rpcSvc = (RepositoryService)GetService(typeof(RepositoryService));
				IMainController mainController = (IMainController)GetService(typeof(IMainController));
				int idOrg = svcMdl.Workflow.ExtendedProperties.AssociatedOrchestrationId;
				if ( idOrg > 0 ) {
					IRepositoryItem item = rpcSvc.GetItem(ItemType.Workflow, idOrg, true);
					if ( item != null ) {
						mainController.OpenDiagram(item);
					}
				} else {
					// not now
					//IRepositoryItem parentItem = null;
					//Repository.Workflow newWf =
					//    rpcSvc.GetNewItem(ItemType.Workflow, false, ref parentItem) as Repository.Workflow; ;
					//if ( newWf != null ) {
					//    newWf.Name = RepositoryService.GetIdentifier(this.Name);
					//    newWf.Type = WorkflowType.Orchestration;
					//    newWf.Save();
					//    Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, newWf);
					//    svcMdl.Workflow.ExtendedProperties.AssociatedOrchestrationId = newWf.ID;
					//}
				}
			} else {
				Operation opProc;
				searchForProcessOperation();
				if ( operationProcess == null ) {
					FormCreateProcess frmCreate = new FormCreateProcess(dc);
					frmCreate.ProcessName = "Start";
					frmCreate.ProcessDescription = "Starts the Orchestration.";

					if ( frmCreate.ShowDialog() == DialogResult.Cancel )
						return;
					bool bSC;
					opProc = repSvc.GetItem(ItemType.Operation, true, dc.RepositoryID, false, false, out bSC) as Operation;
					if ( opProc == null )
						throw new NullReferenceException("Could not create Operation.");

					opProc.Name = frmCreate.ProcessName;
					opProc.Description = frmCreate.ProcessDescription;
					if ( frmCreate.InputBusinessObject != null ) {
						opProc.InputSchema = frmCreate.ProcessInputSchema;
						opProc.InputBusinessObjectId = frmCreate.InputBusinessObject.ID;
						opProc.InputBusinessObjectName = frmCreate.InputBusinessObject.Name;
					}
					if ( frmCreate.OutputBusinessObject != null ) {
						opProc.OutputSchema = frmCreate.ProcessOutputSchema;
						opProc.OutputBusinessObjectId = frmCreate.OutputBusinessObject.ID;
						opProc.OutputBusinessObjectName = frmCreate.OutputBusinessObject.Name;
					}
					opProc.Save();

					if ( listInterfaces.Count > 0 )
						listInterfaces[0].Operations.Add(opProc);
					else {
						InterfaceSymbol i = repSvc.CreateDesignerControl(ItemType.SCA_Export, false) as InterfaceSymbol;
						if ( i == null ) {
							MessageBox.Show("Can't add new interface to component.");
							return;
						}
						i.Operations.Add(opProc);
						AddInterfaceSymbol(i);
					}
					operationProcess = opProc;
				} else {
					opProc = operationProcess;
				}
				dc.Save();
				dc.CreateProcess(this, opProc);
			}
		}

		private void context_OpenVerticalView(object sender, EventArgs e)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			DesignController dc = this.DesignerViewControl.DesignController as DesignController;
			if ( dc == null )
				return;

		}
		#endregion

		#endregion
	}
}
